use nom::{IResult, Parser, branch::alt, bytes::complete::{tag, take}, character::complete::char, combinator::map, sequence::tuple};
use std::fmt::Debug;
fn main() {
    for_each_test(&["abc", "ndd", "ng"], parse_variable);
}

fn parse_abc(input: &str) -> IResult<&str, char> {
    alt((char('a'), char('b'), char('c')))(input)
}
fn parse_abc_tuple(input: &str) -> IResult<&str, (char, char, char)> {
    tuple((char('a'), char('b'), char('c')))(input)
}
fn parse_abc_string(input: &str) -> IResult<&str, &str> {
    tag("abc")(input)
}
fn parse_abc_as_number(input: &str) -> IResult<&str, (i32, i32, i32)> {
    fn translate(ch: char) -> i32 {
        match ch {
            'a' => 1,
            'b' => 2,
            'c' => 3,
            _ => 0,
        }
    }
    tuple((
        map(char('a'), translate),
        (map(char('b'), translate)),
        (map(char('c'), translate)),
    ))(input)
}
fn parse_abc_as_ac(input: &str) -> IResult<&str, (char, char)> {
    tuple((char('a'), char('b'), char('c')))(input)
        .map(|(rest, result)| (rest, (result.0, result.2)))
}
fn parse_variable(input: &str) -> IResult<&str, (char, &str)>{
    tuple((char('n'), take(2usize)))(input)
}
fn for_each_test<'a, P, E, O>(inputs: &'a [&'a str], parser: P)
where
    P: FnOnce(&'a str) -> IResult<E, O>,
    P: Clone,
    E: Debug,
    O: Debug,
{
    inputs.iter().for_each(|input| {
        println!("{:7} {:?}", input.clone(), parser.clone()(input));
    });
}
